# -*- encoding: utf-8 -*-

# Copyright 2010 István Szentandrási
# <etude-music-player@googlegroups.com>

# This file is part of Etude.
#
# Etude is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as 
# published by the Free Software Foundation, either version 3 
# of the License, or (at your option) any later version.
#
# Etude is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Etude. If not, see <http://www.gnu.org/licenses/>.

from . import _

import gobject
import gtk
import pango

import etude.client as ec
import etude.gui as eg
import etude.plugins as ep
import common

class Bookmarks(gtk.Frame):
    
    TARGETS = [('ETUDE_ENCODED_URLS', gtk.TARGET_SAME_APP, 2),] #encoded urls

    def __init__(self, plugin):
        gtk.Frame.__init__(self)
        self.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        self.plugin = plugin

        try:
            icon_theme = gtk.icon_theme_get_default()
            icon_size_menu = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)[0]
            self.pixbuf = icon_theme.load_icon('folder', icon_size_menu, 0)
        except:
            self.pixbuf = None
        
        scroll1 = gtk.ScrolledWindow()
        scroll1.set_policy( gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scroll1.set_shadow_type(gtk.SHADOW_NONE)
        scroll1.set_size_request(150, 70)
        self.add(scroll1)

        self.__create_bookmarks_model()
        self._fill_bookmarks_model()

        self.bview = gtk.TreeView()
        csel = self.bview.get_selection()
        csel.set_mode(gtk.SELECTION_SINGLE)
        self.bview.set_headers_visible(False)
        self.bview.set_model(self.bookmarks_model)
        self.__create_bookmarks_columns()
        scroll1.add(self.bview)

        self.bview.connect('button-press-event', self.on_bookmark_button)
        self.bview.connect('row-activated', self.on_row_activated)
        self.bview.connect('key-press-event', self.on_key_pressed)
        csel.connect('changed', self.bookmark_changed)
        self.bview.connect('drag_data_received', self.on_drag_data_received)
        self.bview.enable_model_drag_dest(self.TARGETS, 
                gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_COPY)

        self.show_all()

    def on_drag_data_received(self, widget, drag_context, x, y, selection,
            info, timestamp):
        data = selection.data
        if info == 2:
            uris = data.strip('\r\n\00 ')
            encoded_uris = uris.split()
            found = False
            for uri in encoded_uris:
                if uri.endswith('/'):
                    self.on_add_bookmark(widget, uri[:-1])
                    found = True
                    break
            if (not found) and (len(encoded_uris) >0):
                dname, sep, filename = uri.rpartition('/')
                self.on_add_bookmark(widget, dname)

    def on_key_pressed(self, widget, event, data):
        if event.keyval == gtk.keysyms.Delete:
            self.on_remove(widget)

    def on_row_activated(self, widget, path, column):
        self.bookmark_changed(self.bview.get_selection, 
                self.bookmarks_model[path][2])
    
    def __create_bookmarks_model(self):
        self.bookmarks_model = gtk.ListStore(gtk.gdk.Pixbuf,
                gobject.TYPE_STRING, gobject.TYPE_STRING)
        self.bookmarks_model.set_sort_column_id(1, gtk.SORT_ASCENDING)

    def _fill_bookmarks_model(self):
        try:
            profname = self.plugin.control.profile['name']
            bs = self.plugin.get_config('bookmarks_'+profname)
            if len(bs) == 0:
                return
        except:
            return
        enc_uris = bs.split()
        for uri in enc_uris:
            begin, sep, end = uri.rpartition('/')
            self.bookmarks_model.append( (self.pixbuf, ec.decode_url(end), uri))

    def on_bookmark_button(self, widget, event, data = None):
        data = self.bview.get_path_at_pos(int(event.x), int(event.y))
        if data == None:
            return False
        if event.button == 3:
            value = self.bookmarks_model[data[0]][2]
            menu = gtk.Menu()
            del_item = gtk.ImageMenuItem(gtk.STOCK_REMOVE)
            del_item.connect('activate', self.on_remove, data[0])
            menu.append(del_item)
            menu.show_all()
            menu.popup(None, None, None, event.button, event.time)
            return True
        elif event.button == 1:
            self.on_row_activated(widget, data[0], 0)
    
    def __create_bookmarks_columns(self):
        """
        For now the first column is a pixbuf
        """
        #tree columns
        coll = gtk.TreeViewColumn()
        render_pixbuf = gtk.CellRendererPixbuf()
        coll.pack_start(render_pixbuf, expand = False)
        coll.add_attribute(render_pixbuf, 'pixbuf', 0)
        render_text = gtk.CellRendererText()
        render_text.set_property('ellipsize', pango.ELLIPSIZE_END)
        coll.pack_start(render_text, expand = True)
        coll.add_attribute(render_text, 'text', 1)
        self.bview.append_column(coll)
        return False

    def bookmark_changed(self, selection, data = None):
        if data == None:
            model, sel_iter = selection.get_selected()
            if sel_iter == None:
                return
            data = model.get_value(sel_iter, 2)
        self.plugin.filelist.set_root_encoded(data)

    def on_remove(self, widget, data = None):
        if data == None:
            csel = self.bview.get_selection()
            model, sel_iter = csel.get_selected()
            if sel_iter == None:
                return False
        else:
            try:
                sel_iter = self.bookmarks_model.get_iter(data)
            except ValueError:
                return False
        self.bookmarks_model.remove(sel_iter)
        self._save_bookmarks()

    def on_add_bookmark(self, widget, data = None):
        if data == None:
            uris = self.plugin.filelist.get_encoded()
            if len(uris) == 0:
                return False
            for isdir, uri in uris:
                if isdir >= 1:
                    data = uri
                    break
            if data == None and len(uris)>0:
                uri = uris[0][1]
                data, sep, end = uri.rpartition('/')
        ttt, tt, dname = data.rpartition('/')
        dname = ec.decode_url(dname)
        self.bookmarks_model.append( (self.pixbuf, dname, data) )
        self._save_bookmarks()

    def _save_bookmarks(self):
        bs = ''
        for row in self.bookmarks_model:
            bs += " "+row[2]
        profname = self.plugin.control.profile['name']
        self.plugin.set_config('bookmarks_'+profname, bs)
        



class DefaultFileBrowser(ep.PluginPanel):
    
    _type = ep.E_PANEL_TYPE_OTHER
    _short_name = "File browser"
    _show_name = _("File browser")
    _short_descr = _("Simple file browser plugin")
    _version = "0.1"
    _unique = "Default_FileBrowser-0.1" # short name + version is enough, just to identify loaded
    _title = _("File Browser")
    _config = {'last': 'file', 'show_bookmarks': '1'}
    __author__ = "Szentandrási István"

    def __init__(self, control):
        ep.PluginPanel.__init__(self, control)
        self.client = self.control.client
        self.set_shadow_type(gtk.SHADOW_NONE)
        self.set_size_request(200, 200)
        
        self.hpaned = gtk.HPaned()
        self.add(self.hpaned)

        frame1 = gtk.VBox()
        scroll1 = gtk.ScrolledWindow()
        scroll1.set_shadow_type(gtk.SHADOW_IN)
        scroll1.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scroll1.set_size_request(200, -1)

        self.filetree = eg.RemoteFileChooser(self.control, type = 'tree')
        self.filelist = eg.RemoteFileChooser(self.control, type = 'list')
        
        vpaned = gtk.VPaned()
        frame1.pack_end(vpaned)

        vpaned.pack2(scroll1)
        self.hpaned.pack1(frame1, resize = False, shrink = True)
        
        self.bookmarks = Bookmarks(self)
        vpaned.pack1(self.bookmarks, False, True)

                
        sel = self.filetree.get_selection()
        sel.set_mode( gtk.SELECTION_SINGLE)
        sel.connect('changed', self.on_filelist_set_root)
        self.filetree.set_headers_visible(False)
        self.filetree.show_only_directories(True)      
        scroll1.add(self.filetree)

        f1_hbox = gtk.HBox()
        frame1.pack_start(f1_hbox, False)
        media_combo_model = gtk.ListStore( str, str)
        media_combo = gtk.ComboBox(media_combo_model)
        f1_hbox.pack_start(media_combo, True, True)
        cell = gtk.CellRendererText()
        media_combo.pack_start(cell, True)
        media_combo.add_attribute(cell, 'text', 0)
        
        #refresh button
        #button = gtk.Button(stock = gtk.STOCK_REFRESH)
        button = gtk.Button()
        button.set_image(gtk.image_new_from_stock(gtk.STOCK_REFRESH,
            gtk.ICON_SIZE_BUTTON))
        f1_hbox.pack_end(button, False, False)
        button.connect('clicked', self.reset_root)
        
        #second panel - filelist

        scroll2 = gtk.ScrolledWindow()
        scroll2.set_shadow_type(gtk.SHADOW_IN)
        scroll2.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scroll2.set_size_request(300, -1) 

        self.filelist.get_selection().set_mode( gtk.SELECTION_MULTIPLE)
        self.filelist.set_rules_hint(True)
        self.filelist.enable_dnd(src = True)
        scroll2.add(self.filelist)
        
        
        self.hpaned.pack2(scroll2, resize = True, shrink = True)
        self.filelist.connect('button-press-event', self.show_add_to_popup)
        self.filelist.connect_after('row-activated', self.song_activated)
 
        self.show_all()
        
        media_combo.connect('changed', self.media_combo_changed)
        self.__fill_media_combo(media_combo)
        if self.get_config('show_bookmarks') != '1':
            self.bookmarks.hide()
    
    def song_activated(self, widget, iter_path, data = None):
        """
        when a music file was double clicked append to playlist
        and start playing it
        """
        def _song_activated(lst):
            self.client.playlist.set_next(len(lst)-1, play = True)
        model = self.filelist.model
        try:
            row_iter = model.get_iter(iter_path)
        except ValueError:
            return True
        isdir, path = model.get(row_iter, eg.RCOLUMN_ISDIR, eg.RCOLUMN_PATH)
        if (isdir == 0):
            self.client.playlist.add_encoded(path)
            self.client.playlist.list_entries(cb = _song_activated)


    def show_add_to_popup(self, widget, event, data = None):
        if event.button == 3:
            sel = widget.get_selection()
            if sel.count_selected_rows() < 2:
                path = widget.get_path_at_pos(int(event.x), int(event.y))
                if path != None:
                    sel.unselect_all()
                    sel.select_path(path[0])
            
            menu = common.create_add_to_playlist_menu(self._add_to_playlist,
                    self.client, enable_all=False)
            menu.show_all()
            menu.popup(None, None, None, 3, event.time)
            return True
     
    def _add_to_playlist(self, widget, playlist, selected=False):
        if playlist == None:
            playlist = "_active"
        paths = self.filelist.get_encoded()
        for isdir, path in paths:
            if isdir == 1:
                self.client.playlist.radd_encoded(path, playlist=playlist)
            elif isdir == 0:
                self.client.playlist.add_encoded(path, playlist=playlist)
    
    def on_filelist_set_root(self, widget, data = None):
        xpath = self.filetree.get_encoded()
        if len(xpath)>0:
            #print(xpath[0])
            self.filelist.set_root_encoded(xpath[0][1])     

    def __fill_media_combo(self, combo):
        combo_model = combo.get_model()
        combo_model.append( (_("Files"), 'file://'))
        combo_model.append( (_("CD"), 'cdda://'))
        active = self.get_config('last')
        if active == 'cd':
            combo.set_active(1)
        else:
            combo.set_active(0)

    def media_combo_changed(self, combo, data = None):
        index = combo.get_active()
        active = combo.get_model()[index][1]
        root = ''
        if active == 'file://':
            root = self.control.profile['music_dir']
            if not root.startswith('/'):
                root = '/'+root
            self.set_config('last', 'file')
        elif active == 'cdda://':
            self.set_config('last', 'cd')
        self.filetree.set_root(active+root, type = active)

    def reset_root(self, widget):
        m = self.filetree.get_model()
        self.filetree.set_root(m.root_path, m.fs_type)
    
    def show_preferences(self, parent):
        """
        Show preferences for file browser
        """
        dialog = gtk.MessageDialog(parent,
                gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                gtk.MESSAGE_OTHER,
                buttons=gtk.BUTTONS_OK_CANCEL
                )
        dialog.set_default_size(300, 200)
        dialog.set_markup("<b>"+_("File browser settings")+"</b>")
        table = gtk.Table(rows = 1, columns = 1)
        tbutton = gtk.CheckButton(_("Show bookmarks"))
        tbutton.set_active(self.get_config('show_bookmarks') == '1')
        table.attach(tbutton, 0, 1, 0, 1,
                xoptions = gtk.FILL|gtk.EXPAND, yoptions = 0)

        dialog.vbox.add(table)
        dialog.show_all()
        res = dialog.run()
        if res == gtk.RESPONSE_OK:
            books = str(int(tbutton.get_active()))
            self.set_config('show_bookmarks', books)
            if books == '1':
                self.bookmarks.show()
            else:
                self.bookmarks.hide()
        dialog.destroy()

